package com.bt.lms.ui.action.school_education.archives.register;

import com.alibaba.fastjson.JSON;
import com.bt.lms.constants.BOConstant;
import com.bt.lms.constants.StuStatusBizTypeConstant;
import com.bt.lms.entity.RegisterInfo;
import com.bt.lms.network.msg.ReqMsg;
import com.bt.lms.network.msg.RespMsg;
import com.bt.lms.ui.page.sys.style.BtnStyle;
import com.bt.lms.ui.vo.school_education.registerInfo.AddRegisterInfoVo;
import com.bt.lms.ui.vo.school_education.registerInfo.EditRegisterInfoVo;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import org.apache.commons.beanutils.BeanUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

/**
 * 添加注册信息验证事件
 */
public class AddRegisterVerify implements EventHandler {

    private VBox vBox;

    public AddRegisterVerify(VBox totalVBox) {
        this.vBox = totalVBox;
    }

    @Override
    public void handle(Event event) {

        //1.获取用户输入
        AddRegisterInfoVo addRegisterInfoVo = getInput();

        //2.验证输入
        String verifyMsg = getVerifyInput(addRegisterInfoVo);

        byte[] bytes = null;
        //3.组包
        if (null == verifyMsg) {
            bytes = handle2Msg(addRegisterInfoVo);
        } else {
            return;
        }
        //组网
        Socket socket = getNet();
        //发送消息
        boolean flag = sengMsg(socket, bytes,addRegisterInfoVo);

    }

    /**
     * 发送消息
     *
     * @param socket             网
     * @param bytes              要发送的字节数组
     * @param addRegisterInfoVo vo对象
     * @return 是否成功
     */
    private boolean sengMsg(Socket socket, byte[] bytes, AddRegisterInfoVo addRegisterInfoVo) {
        OutputStream out = null;
        try {
            out = socket.getOutputStream();
            out.write(bytes);
            out.flush();



            //读取响应包
            InputStream in = socket.getInputStream();
            byte[] buf = new byte[1024];
            in.read(buf);

            RespMsg respMsg = RespMsg.toRespMsg(buf);
            String data = respMsg.getData();
            if (data != null){
                Alert alert = new Alert(Alert.AlertType.WARNING);
                alert.setContentText("保存成功");
                alert.show();
            }
            //界面回显
            VBox vBox1 = initPage(addRegisterInfoVo);
            ObservableList<Node> children = vBox.getChildren();
            int size = children.size();
            children.set(size - 1,vBox1);


            //关闭资源
            out.close();
            socket.close();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return true;
    }

    /**
     * 界面回显
     * @param addRegisterInfoVo vo对象
     */
    private VBox initPage(AddRegisterInfoVo addRegisterInfoVo) {
        VBox vBox1 = new VBox();
        double baseWidth = 1230;
        HBox hBox = new HBox();
        hBox.setPrefWidth(baseWidth);
        hBox.setAlignment(Pos.CENTER_RIGHT);
        hBox.setSpacing(10);
        Insets insets1 = new Insets(0, 50, 0, 0);
        hBox.setPadding(insets1);
        Button editBtn = new Button("💻编辑");
        Button deleteBtn = new Button("❌删除");
        hBox.getChildren().add(editBtn);
        hBox.getChildren().add(deleteBtn);
        vBox1.getChildren().add(hBox);
        //按钮样式
        BtnStyle.saveBtn(editBtn);
        BtnStyle.cancelBtn(deleteBtn);
        editBtn.setCursor(Cursor.HAND);
        deleteBtn.setCursor(Cursor.HAND);


        HBox totalHBox = new HBox();
        totalHBox.setPrefWidth(baseWidth);
        totalHBox.setSpacing(10);

        //编辑
        RegisterEditAction registerEditAction = new RegisterEditAction(vBox,totalHBox);
        editBtn.setOnAction(registerEditAction);
        //删除
        deleteBtn.setOnAction(event -> {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
            alert.setContentText("您确定要删除这条注册信息嘛");
            alert.show();
        });

        VBox one1 = new VBox();
        one1.setPrefWidth(baseWidth / 8);
        one1.setSpacing(10);
        Label registerConditionLab = new Label("注册状况");
        Label noRegisterCauseLab = new Label("未注册原因");
        Label schoolYearLab = new Label("学年（度）");
        one1.getChildren().addAll(registerConditionLab, noRegisterCauseLab, schoolYearLab);
        totalHBox.getChildren().add(one1);

        VBox one2 = new VBox();
        one2.setPrefWidth(baseWidth / 6);
        one2.setSpacing(10);
        //注册状况
        Integer state = addRegisterInfoVo.getState();
        String leave = "";
        switch (state){
            case 1:
                leave = "注册";
                break;
            case 2:
                leave = "未注册";
                break;
            case 3:
                leave = "未报到";
                break;
        }
        Label registerConditionLabMes = new Label(leave);
        //未注册原因
        Label noRegisterCauseLabMes = new Label(addRegisterInfoVo.getNotRegisterCause());
        //学年度
        Label schoolYearLabMes = new Label(addRegisterInfoVo.getSchoolYear());
        one2.getChildren().addAll(registerConditionLabMes, noRegisterCauseLabMes, schoolYearLabMes);
        totalHBox.getChildren().add(one2);


        VBox one3 = new VBox();
        one3.setPrefWidth(baseWidth / 8);
        one3.setSpacing(10);
        Label registerDataLab = new Label("注册日期");
        Label noRegisterWhereaboutsLab = new Label("未注册/报道去向");
        Label semesterLab = new Label("学期");
        one3.getChildren().addAll(registerDataLab, noRegisterWhereaboutsLab, semesterLab);
        totalHBox.getChildren().add(one3);

        VBox one4 = new VBox();
        one4.setPrefWidth(baseWidth / 6);
        one4.setSpacing(10);
        //注册日期
        LocalDate date = addRegisterInfoVo.getDate();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = date.format(dateTimeFormatter);
        Label registerDataLabMes = new Label(format);
        //未注册报到去向
        Label noRegisterWhereaboutsLabMes = new Label(addRegisterInfoVo.getNotRegisterGo());
        //学期
        Label semesterLabMes = new Label(addRegisterInfoVo.getSemester());
        one4.getChildren().addAll(registerDataLabMes, noRegisterWhereaboutsLabMes, semesterLabMes);
        totalHBox.getChildren().add(one4);


        VBox one5 = new VBox();
        one5.setPrefWidth(baseWidth / 8);
        one5.setSpacing(10);
        Label reportDataLab = new Label("报到日期");
        Label whetherAskLab = new Label("是否请假");
        Label classroomLab = new Label("所在班级");
        one5.getChildren().addAll(reportDataLab, whetherAskLab, classroomLab);
        totalHBox.getChildren().add(one5);

        VBox one6 = new VBox();
        one6.setPrefWidth(baseWidth / 6);
        one6.setSpacing(10);
        //报到日期
        LocalDate gotoDate = addRegisterInfoVo.getGotoDate();
        DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format1 = gotoDate.format(dateTimeFormatter1);
        Label reportDataLabMes = new Label(format1);
        //是否请假
        Integer isVacate = addRegisterInfoVo.getIsVacate();
        String leave1 = "";
        switch (isVacate){
            case 1:
                leave1 = "是";
                break;
            case 2:
                leave1 = "否";
                break;
        }
        Label whetherAskLabMes = new Label(leave1);
        //所在班级
        Label classroomLabMes = new Label(addRegisterInfoVo.getClassroom());
        one6.getChildren().addAll(reportDataLabMes, whetherAskLabMes, classroomLabMes);
        totalHBox.getChildren().add(one6);
        vBox1.getChildren().add(totalHBox);

        return vBox1;
    }

    /**
     * 获取网络
     *
     * @return 网
     */
    private Socket getNet() {
        Socket socket = null;

        try {
            socket = new Socket("127.0.0.1", 8888);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


        return socket;
    }

    /**
     * 组包
     *
     * @param addRegisterInfoVo vo对象
     * @return byte字节数组
     */
    private byte[] handle2Msg(AddRegisterInfoVo addRegisterInfoVo) {
        //消息
        ReqMsg reqMsg = new ReqMsg();
        //业务类型
        reqMsg.setBizType(StuStatusBizTypeConstant.REGISTER_INFO_BIZ_TYPE_ADD);
        //注册信息entity
        RegisterInfo registerInfo = new RegisterInfo();
        try {
            BeanUtils.copyProperties(registerInfo, addRegisterInfoVo);
            registerInfo.setId(1L);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        String registerStr = JSON.toJSONString(registerInfo);
        reqMsg.setData(registerStr);

        return reqMsg.toBytes();

    }

    /**
     * 验证用户输入
     *
     * @param addRegisterInfoVo vo对象
     * @return 验证后的str
     */
    private String getVerifyInput(AddRegisterInfoVo addRegisterInfoVo) {
        String msg = "";


        if (addRegisterInfoVo.getState() != null) {
        }

        long now = -1;
        if (addRegisterInfoVo.getDate() != null) {
            long data = addRegisterInfoVo.getDate().atStartOfDay()
                    .toInstant(ZoneOffset.of("+8")).toEpochMilli();
            now = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            if (data > now) {
                msg += "注册日期在当前时间之前\r\n";
            }
        }

        if (addRegisterInfoVo.getGotoDate() != null) {
            long data = addRegisterInfoVo.getGotoDate().atStartOfDay()
                    .toInstant(ZoneOffset.of("+8")).toEpochMilli();
            if (data > now) {
                msg += "报到日期在当前时间之前\r\n";
            }
        }

        String notRegisterCause = addRegisterInfoVo.getNotRegisterCause();
        if (notRegisterCause != null) {
            if (notRegisterCause.length() > 24) {
                msg += "未报到原因在0-24位之间之前\r\n";
            }
        }

        String notRegisterGo = addRegisterInfoVo.getNotRegisterGo();
        if (notRegisterGo != null) {
            if (notRegisterGo.length() > 32) {
                msg += "未注册/报到去向在0-32位之间之前\r\n";
            }
        }

        if (addRegisterInfoVo.getIsVacate() != null){

        }

        String schoolYear = addRegisterInfoVo.getSchoolYear();
        if (schoolYear != null) {
            if (schoolYear.length() > 24) {
                msg += "学年度在0-24位之间之前\r\n";
            }
        }

        String semester = addRegisterInfoVo.getSemester();
        if (semester != null) {
            if (semester.length() > 24) {
                msg += "学期在0-24位之间之前\r\n";
            }
        }

        String clas = addRegisterInfoVo.getClassroom();
        if (clas != null) {
            if (clas.length() > 24) {
                msg += "班级名称在0-24位之间之前\r\n";
            }
        }

        if (!msg.equals("")){
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setContentText(msg);
            alert.show();
        }
        if (msg.equals("")){
            msg = null;
        }

        return msg;

    }

    /**
     * 获取用户输入
     *
     * @return
     */
    private AddRegisterInfoVo getInput() {
        AddRegisterInfoVo addRegisterInfoVo = new AddRegisterInfoVo();

        ComboBox conditionCB = (ComboBox) this.vBox.lookup("#conditionCB");

        if (conditionCB.getValue() != null) {
            int leave = -1;
            String conditionCBValue = (String) conditionCB.getValue();
            switch (conditionCBValue) {
                case "注册":
                    leave = BOConstant.REGISTER_INFO_STATE_REGISTER;
                    break;
                case "未注册":
                    leave = BOConstant.REGISTER_INFO_STATE_UNREGISTERED;
                    break;
                case "未报到":
                    leave = BOConstant.REGISTER_INFO_STATE_NO_SHOW;
                    break;
            }
            addRegisterInfoVo.setState(leave);
        }

        DatePicker registerTimeDP = (DatePicker) this.vBox.lookup("#registerTimeDP");
        LocalDate registerTimeDPValue = registerTimeDP.getValue();
        addRegisterInfoVo.setDate(registerTimeDPValue);

        DatePicker checkInTimeDP = (DatePicker) this.vBox.lookup("#checkInTimeDP");
        LocalDate checkInTimeDPValue = checkInTimeDP.getValue();
        addRegisterInfoVo.setGotoDate(checkInTimeDPValue);

        TextField notRegisterCauseTF = (TextField) this.vBox.lookup("#notRegisterCauseTF");
        String notRegisterCauseTFStr = notRegisterCauseTF.getText().trim();
        addRegisterInfoVo.setNotRegisterCause(notRegisterCauseTFStr);

        TextField notRegisterGoTF = (TextField) this.vBox.lookup("#notRegisterGoTF");
        String notRegisterGoTFStr = notRegisterGoTF.getText().trim();
        addRegisterInfoVo.setNotRegisterGo(notRegisterGoTFStr);

        ComboBox vacateCB = (ComboBox) this.vBox.lookup("#vacateCB");
        if (vacateCB.getValue() != null) {
            int leave = -1;
            String vacateCBValue = (String) vacateCB.getValue();
            switch (vacateCBValue) {
                case "是":
                    leave = BOConstant.REGISTER_INFO_DELETED_NO;
                    break;
                case "否":
                    leave = BOConstant.REGISTER_INFO_DELETED_YES;
                    break;
            }
            addRegisterInfoVo.setIsVacate(leave);
        }

        TextField schoolYearTF = (TextField) this.vBox.lookup("#schoolYearTF");
        String schoolYearTFStr = schoolYearTF.getText().trim();
        addRegisterInfoVo.setSchoolYear(schoolYearTFStr);

        TextField semesterTF = (TextField) this.vBox.lookup("#semesterTF");
        String semesterTFStr = semesterTF.getText().trim();
        addRegisterInfoVo.setSemester(semesterTFStr);

        TextField classTF = (TextField) this.vBox.lookup("#classTF");
        String classTFStr = classTF.getText().trim();
        addRegisterInfoVo.setClassroom(classTFStr);


        return addRegisterInfoVo;
    }
}
